/**
 * core.js - 批量合并订单核心功能
 * 实现批量合并订单的主要逻辑
 */

// 全局错误处理器
process.on('uncaughtException', (error) => {
    console.error('未捕获的异常:', error);
});

// 导入外部模块
const { customRequire, checkPluginDependencies } = require('./utils.js');
const { chromium } = customRequire('playwright');
const fs = require('fs');
const path = require('path');
const winston = customRequire('winston');

// 导入本地模块
const LoginPage = require('./login_page.js').LoginPage;
const FirstPage = require('./first_page.js').FirstPage;
const OrderListPage = require('./order_list_page.js');
const { OrderDetailPage } = require('./order_detail_page.js');
const { sendMonitoringData } = require("./user-data.js")
const manifest = require('./manifest.json');

// 检查模块是否已缓存
if (require.cache[require.resolve('playwright')]) {
    delete require.cache[require.resolve('playwright')];
}

// 初始化日志记录器
const logger = winston.createLogger({
    level: 'info',
    format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.printf(({ timestamp, level, message }) => {
            return `${timestamp} ${level}: ${message}`;
        })
    ),
    transports: [
        new winston.transports.Console(),
        new winston.transports.File({ filename: 'batch-combine.log' })
    ]
});

// 主函数，接收从前端传递的参数
async function main(address, isHeadless, orderNumbers, userSettings) {
    try {
        // 根据地址判断环境
        const isPRD = address.includes('cnapp.sgs.net');
        // 注意：isHeadless在UI中表示是否显示步骤，而在这里需要取反
        const headless = !isHeadless;
        
        // 调用批量合并函数
        const result = await batchCombine(orderNumbers, isPRD, headless, userSettings);
        
        // 处理结果，转换为前端需要的格式
        const processedResults = [];
        
        // 如果有详细结果，添加到处理结果中
        if (result && result.details && Array.isArray(result.details)) {
            result.details.forEach(detail => {
                processedResults.push({
                    orderNo: detail.orderNo,
                    success: detail.success,
                    message: detail.message || '',
                    monitoringStatus: detail.monitoringStatus,
                    monitoringMessage: detail.monitoringMessage
                });
            });
        } else {
            // 如果没有详细结果，创建一个简单的结果
            orderNumbers.forEach(orderNo => {
                processedResults.push({
                    orderNo: orderNo,
                    success: false,
                    message: '处理结果未知'
                });
            });
        }
        
        return processedResults;
    } catch (error) {
        console.error('执行批量合并时出错:', error);
        throw error;
    }
}

/**
 * 打开浏览器并登录
 * @param {boolean} isPRD - 是否为生产环境
 * @param {boolean} headless - 是否为无头模式
 * @returns {Promise<Object>} - 返回浏览器和页面对象
 */
async function openBrowser(isPRD, headless) {
    // 发送日志
    const sendLog = (message, type = 'info') => {
        logger.info(message);
        console.log(`[${type}] ${message}`);
    };

    // 发送错误
    const sendError = (message) => {
        logger.error(message);
        console.error(`[error] ${message}`);
    };

    try {
        sendLog('正在启动浏览器...');
        
        // 根据是否为无头模式设置不同的启动参数
        const launchOptions = {
            headless: headless,
            executablePath: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
            args: headless ? [
                // 无头模式专用参数
                '--no-sandbox',
                '--disable-setuid-sandbox',
                '--disable-dev-shm-usage',
                '--disable-accelerated-2d-canvas',
                '--no-first-run',
                '--no-zygote',
                '--disable-gpu',
                '--disable-features=VizDisplayCompositor',
                '--disable-features=IsolateOrigins,site-per-process',
                '--window-size=1920,1080'
            ] : [
                // 有头模式参数
                '--start-maximized',
                '--disable-features=IsolateOrigins,site-per-process'
            ]
        };
        
        const browser = await chromium.launch(launchOptions);

        // 创建新页面，为无头模式设置合适的视口
        const contextOptions = headless ? 
            { viewport: { width: 1920, height: 1080 } } : 
            { viewport: null };
            
        const context = await browser.newContext(contextOptions);
        const page = await context.newPage();

        // 设置超时，无头模式使用更长的超时时间
        const timeout = headless ? 45000 : 30000;
        page.setDefaultTimeout(timeout);

        // 确定环境URL
        const baseUrl = isPRD 
            ? 'http://cnapp.sgs.net/gpo-web/#/' // 生产环境URL
            : 'http://cnapp-uat.sgs.net/sgsLogin/';     // UAT环境URL

        sendLog(`正在打开${isPRD ? 'PRD' : 'UAT'}环境: ${baseUrl}`);
        
        const login = new LoginPage(page);
        await login.GPOOpen(baseUrl);
        await login.singleSignOn();
        sendLog('浏览器初始化完成');
        return { browser, page, context };
    } catch (error) {
        sendError(`浏览器初始化失败: ${error.message}`);
        throw error;
    }
}

/**
 * 批量合并订单
 * @param {Array<string>} orderNumbers - 订单号数组
 * @param {boolean} isPRD - 是否为生产环境
 * @param {boolean} headless - 是否为无头模式
 * @param {Object} userSettings - 用户设置
 * @returns {Promise<Object>} - 处理结果对象
 */
async function batchCombine(orderNumbers, isPRD, headless, userSettings) {
    let browser = null;
    let page = null;
    let context = null;
    let successCount = 0;
    let trCount = 0;
    const details = [];
    
    // 记录用户设置（如果有）
    if (userSettings) {
        logger.info('使用用户设置: ' + JSON.stringify(userSettings));
    } else {
        logger.info('未提供用户设置，使用默认设置');
    }
    
    // 发送日志
    const sendLog = (message, type = 'info') => {
        if (type === 'info') {
            logger.info(message);
        } else if (type === 'error') {
            logger.error(message);
        } else if (type === 'warning') {
            logger.warn(message);
        }
        console.log(`[${type}] ${message}`);
    };

    try {
        // 打开浏览器
        const browserData = await openBrowser(isPRD, headless);
        browser = browserData.browser;
        page = browserData.page;
        context = browserData.context;

        sendLog(`订单数量: ${orderNumbers.length}`);
        
        // 导航到订单列表页面
        const firstPage = new FirstPage(page);
        await firstPage.orderListEntry();

        // 搜索订单
        const orderListPage = new OrderListPage(page);
        await orderListPage.search_order_no_batch(orderNumbers);
        
        const orderListBodyXpath = `//*[@id="pane-orderListTab"]/div/div/div/div/div[2]/div[4]/div[2]/table/tbody`;
        const orderListFirstTr = `//*[@id="pane-orderListTab"]/div/div/div/div/div[2]/div[4]/div[2]/table/tbody/tr[1]`;
        await page.waitForSelector(orderListFirstTr);
        trCount = await page.locator(`${orderListBodyXpath}/tr`).count();
        
        for (let trNo = 1; trNo <= trCount; trNo++) {
            let orderNoContent = '';
            let newPage = null;
            let isProcessingSuccessful = false;
            
            try {
                // 获取订单号
                const orderNoXpath = `${orderListBodyXpath}/tr[${trNo}]/td[2]/div/a`;
                orderNoContent = await page.locator(orderNoXpath).textContent() || '未知订单号';
                sendLog(`处理进度 [${trNo}/${trCount}]：${orderNoContent}`);
                
                // 点击订单号，打开详情页
                await page.locator(orderNoXpath).click();

                // 获取新打开的标签页
                let pages = context.pages();
                newPage = pages[pages.length-1]; // 最后一个标签页（即新标签页）
                
                // 等待页面加载完成
                await newPage.waitForLoadState('networkidle');
                await newPage.waitForTimeout(1000); // 额外等待确保页面完全渲染
                
                // 检查是否存在Chinese radio元素，如果存在则点击
                try {
                    const chineseRadio = newPage.getByRole('radio', { name: 'Chinese' });
                    const isChineseRadioVisible = await chineseRadio.isVisible().catch(() => false);
                    if (isChineseRadioVisible) {
                        sendLog(`发现Chinese radio元素，正在点击...`);
                        await chineseRadio.click();
                        await newPage.waitForTimeout(500); // 等待页面更新
                    }
                } catch (error) {
                    // 如果找不到Chinese radio元素，继续执行后续操作
                    sendLog(`未找到Chinese radio元素或点击失败: ${error.message}`);
                }
                
                // 点击Combine按钮
                try {
                    // 导入withRetry函数
                    const { withRetry } = require('./playwrightUtils');
                    
                    // 使用withRetry机制处理点击Combine To Form按钮
                    await withRetry(newPage, null, async () => {
                        await newPage.getByRole('button', { name: 'Combine To Form' }).click();
                    }, '点击Combine To Form按钮');
                } catch (error) {
                    sendLog(`定位Combine按钮失败: ${error.message}`, 'error');
                    details.push({
                        orderNo: orderNoContent,
                        success: false,
                        message: `定位Combine按钮失败: ${error.message}`
                    });
                    continue;
                }
                
                // 点击Save按钮
                const orderDetailPage = new OrderDetailPage(newPage);
                await orderDetailPage.clickAllSave();
                
                // 获取Save成功信息
                const selector = 'div.el-notification__content p';
                const titleSelector = 'h2.el-notification__title';
                const element = await newPage.waitForSelector(selector);
                const titleElement = await newPage.waitForSelector(titleSelector);
                const content = await element.innerText();
                const title = await titleElement.innerText();
                
                if (content == 'Save Success!') {
                    sendLog(`${orderNoContent} combine to form 消息${title}: ${content}`, 'info');
                    sendLog(`订单处理完成：${orderNoContent}`, 'info');
                    successCount++;
                    details.push({
                        orderNo: orderNoContent,
                        success: true,
                        message: 'Save Success!'
                    });
                    const monitoringData = {
                        user_name: userSettings.email?.split('@')[0] || 'unknown',
                        user_location: userSettings.site || 'unknown',
                        rpa_id: "138",
                        rpa_name: "GPO_BatchCombineToForm",
                        rpa_version: manifest.version,
                        occurrence: new Date().toLocaleString('en-US', {
                            weekday: 'short',
                            day: '2-digit',
                            month: 'short',
                            year: 'numeric',
                            hour: '2-digit',
                            minute: '2-digit',
                            second: '2-digit',
                            hour12: false
                        }),
                        info: "GPO Batch Click CombineToForm Button.",
                        extra: orderNoContent
                    };
                    const monitoringResult = await sendMonitoringData([monitoringData]);
                    // console.log('数据：', monitoringData);
                    // 将监控数据发送状态添加到结果对象中
                    details[details.length - 1].monitoringStatus = monitoringResult.success;
                    details[details.length - 1].monitoringMessage = monitoringResult.message;
                    console.log('detail: ', details)
                } else {
                    sendLog(`${orderNoContent} combine to form 消息${title} : ${content}`, 'error');
                    details.push({
                        orderNo: orderNoContent,
                        success: false,
                        message: content
                    });
                }
                
                isProcessingSuccessful = true;
                if (newPage && !newPage.isClosed()) {
                    await newPage.close();
                    await page.waitForTimeout(1000); // 页面关闭后的缓冲时间
                }
            } catch (error) {
                // 修改错误处理逻辑，区分页面关闭错误和其他错误
                if (isProcessingSuccessful && error.message.includes('has been closed')) {
                    sendLog(`订单 ${orderNoContent} 处理完成 (页面已正常关闭)`);
                } else {
                    sendLog(`订单 ${orderNoContent} 处理失败: ${error.message}`, 'error');
                    details.push({
                        orderNo: orderNoContent,
                        success: false,
                        message: `处理失败: ${error.message}`
                    });
                }
                continue;
            } finally {
                try {
                    if (newPage && !newPage.isClosed()) {
                        await newPage.close();
                        await page.waitForTimeout(1000); // 页面关闭后的缓冲时间
                    }
                } catch (finallyError) {
                    sendLog(`关闭页面时出错 ${orderNoContent}: ${finallyError.message}`, 'error');
                }
            }
        }

        sendLog(`批量合并完成，成功处理 ${successCount}/${trCount} 个订单，成功率：${((successCount / trCount) * 100).toFixed(1)}%`, 'success');
        return { successCount, trCount, details };
    } catch (outerError) {
        sendLog(
            `批量合并处理过程中发生错误，已成功处理 ${successCount}/${trCount} 个订单`,
            'error'
        );
        throw outerError;
    } finally {
        // 关闭浏览器
        try {
            if (browser) {
                await browser.close();
                sendLog('浏览器已关闭');
            }
        } catch (browserCloseError) {
            sendLog(`关闭浏览器时出错: ${browserCloseError.message}`, 'error');
        }
    }
}

// 导出main函数作为模块的主入口点
module.exports = main;

// 启动前检测依赖完整性
checkPluginDependencies(['playwright', 'winston']);